POV-Ray : Newsgroups : povray.general : recursively defined objects and memory : recursively defined objects and memory Server Time
29 Jul 2024 02:25:04 EDT (-0400)
  recursively defined objects and memory  
From: Anthony D  Baye
Date: 13 Aug 2013 03:30:01
Message: <web.5209e02df7af87b1328783aa0@news.povray.org>
Over the weekend, I was trying to implement a CSG method for generating random
planets.

The basic algorithm is simple: Take a sphere, cut it in half along a random
plane, scale each half independently by some small amount, iterate.

#macro Planet(baseRad)

#local Base = sphere { 0.0, baseRad }
#local Plt = Base

#local A = 0;
#while(A < 16)

    #local rT = <Rand_Gauss(0.0, 0.33, RdmA), Rand_Gauss(0.0, 0.33, RdmB),
Rand_Gauss(0.0, 0.33, RdmC)>*360;
    #declare Plt =
    union {
        intersection {
            object { Plt }
            plane { y, 0 rotate rT }
                scale (1 + Rand_Gauss(0.0, 0.33, RdmA)*0.15)
            }
        intersection {
            object { Plt }
            plane { -y, 0 rotate rT }
                scale (1 + Rand_Gauss(0.0, 0.33, RdmB)*0.15)
            }
            bounded_by { box { -baseRad*0.625, baseRad*0.625 }}
        }

#local A = A + 1;
#end

    Plt

#end

now, from what I've read, it takes more than a thousand iterations to get good
results, but trying to do just fifty iterations makes POV do an imitation of
PAC-Man with my memory and swap space.  All 16GB of it.

I don't know if this is a bug or a natural limitation of the geometry parsing
engine.

Since doing it with CSG proved unreasonable, I thought I'd try functions
instead.

This is as far as I got:

#declare baseFn = function(x,y,z,r) { sqrt(x*x + y*y + z*z) - r }
#declare boxFN = function { y * sqrt(x*x + z*z) }
#declare half = function { max(baseFn(x,y,z,3),boxFN(x, y, z)) }

isosurface {
    function { min( half(x,y,z), half(x, -y, z)*Rand_Gauss(0.0,0.33,RdmB)) }
    threshold 0
    max_gradient 5
    contained_by{ box {-5, 5} }
        pigment { White }
    }

the problem is imposing a rotation on the FUNCTION, rather than the isosurface
as a whole.  I know how to impose a rotation around a given axis, but going from
there to rotating about all axes is somewhat more problematic without a matrix
transformation (which would be decidedly more elegant, but harder to compute on
the fly)

The rotation transform would be done on the boxFN(...) function in the half
object, and each iteration would redefine baseFn(...)

scaling each half would then be no trouble with variable substitution.

The only way I've come up with to solve the rotation problem is a separate
transformation (using a separate angle variable) for each axis.  It would be
messy, but it could work.

My final option for using this algorithm is some kind of pigment, constructed in
much the same fashion, but I'm not sure which patterns I'd use, or if I'd have
to construct functions for the patterns I'd need.

If anyone has suggestions, I'd welcome them.

Regards,
A.D.B.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.